package com.grantheath.erebus.controller.initializationCommands 
{
	import com.grantheath.erebus.model.enum.notifications.ErebusURLNotifications;
	import com.grantheath.erebus.model.enum.notifications.ErebusInitializationNotifications;
	import com.grantheath.erebus.model.enum.names.ErebusProxyNames;
	import com.grantheath.erebus.model.interfaces.IErebusPageNode;
	import com.grantheath.erebus.model.interfaces.IErebusSiteTreeProxy;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.interfaces.ICommand;
	import org.puremvc.as3.patterns.command.SimpleCommand;

	/**
	 * @author grantheath
	 */
	public class ErebusInitializeQueuesCommand extends SimpleCommand implements ICommand 
	{
		private var _siteTreeProxy : IErebusSiteTreeProxy;

		override public function execute(notification : INotification) : void
		{	
			_siteTreeProxy = facade.retrieveProxy(ErebusProxyNames.SITE_TREE_PROXY) as IErebusSiteTreeProxy;
			if(_siteTreeProxy) {
				var URL : String = notification.getBody() as String;
				var URLArray : Array = getURLArray(URL);
				var URLNodes : Array = new Array();
				var newLoadQueue : Array = new Array();
				var newDisplayQueue : Array = new Array();
				var newHideQueue : Array = new Array();
				var newUninitializeQueue : Array = new Array();
				var targetNode : IErebusPageNode;
				var sortNode : IErebusPageNode;
				var looping : Boolean = true;
				
				//a transition is starting
				_siteTreeProxy.isTransitioning = true;
				//make sure site tree root is loaded
				URLNodes.push(_siteTreeProxy.tree);
				//get the page nodes referenced in the URL
				for(var i : uint = 0;i < URLArray.length;i++) {
					var sortArray : Array = URLArray.slice(0, i + 1);
					var URLNode : IErebusPageNode = _siteTreeProxy.getPageNodeFromURLArray(sortArray);
					
					if(URLNode) {
						URLNodes.push(URLNode);
					} else {
						facade.sendNotification(ErebusURLNotifications.HANDLE_INVALID_URL, URL);
						break;
					}
				}
				//handle default children
				if(URLNodes.length > 0) {
					sortNode = URLNodes[URLNodes.length - 1];
				} else {
					sortNode = URLNodes[0];
				}
				if(sortNode){
					while(looping) {
						if(sortNode.defaultChild) {
							sortNode = sortNode.defaultChild;
							URLNodes.push(sortNode);
						} else {
							looping = false;
						}
					}
				}
				//build load and display queues
				for each(sortNode in URLNodes) {
					if(!_siteTreeProxy.isLoaded(sortNode)) {
						newLoadQueue.push(sortNode);
					}
					if(!_siteTreeProxy.isDisplayed(sortNode)) {
						newDisplayQueue.push(sortNode);
					}
				}
				//build uninitialize queue
				for each(sortNode in _siteTreeProxy.loadedPages) {
					if(sortNode != _siteTreeProxy.tree) {
						if(URLNodes.indexOf(sortNode) == -1) {
							newUninitializeQueue.push(sortNode);
						}
					}
				}
				//build hide queue
				for each(sortNode in _siteTreeProxy.displayedPages) {
					if(sortNode != _siteTreeProxy.tree) {
						if(URLNodes.indexOf(sortNode) == -1) {
							newHideQueue.push(sortNode);
						}
					}
				}
				//TODO get rid of extra trace statements
				trace("load queue:");
				for each(sortNode in newLoadQueue) {
					trace("\t" + sortNode);
				}
				trace("display queue:");
				for each(sortNode in newDisplayQueue) {
					trace("\t" + sortNode);
				}
				trace("unitialize queue:");
				for each(sortNode in newUninitializeQueue) {
					trace("\t" + sortNode);
				}
				trace("hide queue:");
				for each(sortNode in newHideQueue) {
					trace("\t" + sortNode);
				}
				_siteTreeProxy.loadQueue = newLoadQueue;
				_siteTreeProxy.displayQueue = newLoadQueue;
				_siteTreeProxy.uninitializeQueue = newUninitializeQueue.reverse();
				_siteTreeProxy.hideQueue = newHideQueue.reverse();
				targetNode = URLNodes[URLNodes.length - 1];
				//URL rewritting only works as expected in firefox
				//don't do it for now
				/*
				if(targetNode) {
					sendNotification(ErebusURLNotifications.REWRITE_URL, targetNode.treePath);
				} else {
					sendNotification(ErebusURLNotifications.REWRITE_URL, _siteTreeProxy.tree);
				}
				 */
				sendNotification(ErebusInitializationNotifications.INITIALIZE_TRANSITION);
			} else {
				//TODO better no tree proxy error
				throw new Error("NO TREE PROXY ERROR");
			}
		}

		private function getURLArray(URL : String) : Array
		{
			var splitURL : Array;
			
			splitURL = URL.split("?");
			splitURL = String(splitURL[0]).split("/").filter(_siteTreeProxy.filterNullArrayValues);
			return splitURL;
		}
	}
}